/* * Copyright 2006-2015 WebPKI.org (http://webpki.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package temp1; import java.io.DataInputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Vector; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import org.webpki.json.JSONObjectReader; import org.webpki.json.JSONObjectWriter; import org.webpki.json.JSONOutputFormats; import org.webpki.json.JSONParser; import org.webpki.net.HTTPSWrapper; // CLI test program for manually activating the target application import static org.webpki.tapconnect.TapConnectProperties.*; public class CallingW2NB { static Logger logger = Logger.getLogger("MyLog"); static Process process; static StdinJSONPipe stdin; static StdoutJSONPipe stdout; static class StdinJSONPipe { String jsonString; DataInputStream dis; StdinJSONPipe() { dis = new DataInputStream(process.getInputStream()); } JSONObjectReader readJSONObject() throws IOException { byte[] byteBuffer = new byte[4]; dis.readFully(byteBuffer, 0, 4); // Code only works for little-endian machines // Network order, heard of that Google? int l = (byteBuffer[3]) << 24 | (byteBuffer[2] & 0xff) << 16 | (byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff); if (l > 100000) System.exit(3); byte[] utf8 = new byte[l]; dis.readFully(utf8); jsonString = new String(utf8, "UTF-8"); return JSONParser.parse(utf8); } String getJSONString () { return jsonString; } } static class StdoutJSONPipe { OutputStream os; StdoutJSONPipe() { os = process.getOutputStream(); } String writeJSONObject (JSONObjectWriter ow) throws IOException { byte[] utf8 = ow.serializeJSONObject(JSONOutputFormats.NORMALIZED); int l = utf8.length; // Code only works for little-endian machines // Network order, heard of that Google? byte[] blob = new byte[l + 4]; blob[0] = (byte) l; blob[1] = (byte) (l >>> 8); blob[2] = (byte) (l >>> 16); blob[3] = (byte) (l >>> 24); for (int i = 0; i < l; i++) { blob[4 + i] = utf8[i]; } os.write(blob); os.flush(); return new String(utf8, "UTF-8"); } } static JSONObjectReader post(String url, JSONObjectWriter json, int timeout) throws IOException { HTTPSWrapper wrap = new HTTPSWrapper(); wrap.setTimeout(timeout); wrap.setHeader("Content-Type", JSON_CONTENT_TYPE); wrap.setRequireSuccess(true); wrap.makePostRequest(url, json.serializeJSONObject(JSONOutputFormats.NORMALIZED)); // We expect JSON, yes if (!wrap.getRawContentType().equals(JSON_CONTENT_TYPE)) { throw new IOException("Content-Type must be \"" + JSON_CONTENT_TYPE + "\" , found: " + wrap.getRawContentType()); } return JSONParser.parse(wrap.getData()); } public static void main(final String[] args) { if (args.length != 2) { System.out.println("1: full proxy/install path\n2: URL-to-NFC-service"); System.exit(3); } String step = "initial"; try { logger.setUseParentHandlers(false); System.setProperty("java.util.logging.SimpleFormatter.format", "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n"); FileHandler fh = new FileHandler(args[0] + File.separator + "logs" + File.separator + "w2nb-caller.log"); logger.addHandler(fh); SimpleFormatter formatter = new SimpleFormatter(); fh.setFormatter(formatter); JSONObjectReader init = post(args[1], new JSONObjectWriter(), STANDARD_TIMEOUT); logger.info("Invocation:" + init); String application = init.getString(APPLICATION_JSON); String invocationUrl = init.getString(INVOCATION_URL_JSON); String optionalData = init.getString(OPTIONAL_DATA_JSON); init.checkForUnread(); step = "starting"; Vector<String> commands = new Vector<String>(); commands.add("java"); commands.add("-Djava.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n"); if (System.getProperty("os.name").toLowerCase().startsWith("windows")) { commands.add("-Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } commands.add("-jar"); commands.add(args[0] + File.separator + "apps" + File.separator + application + File.separator + application + ".jar"); commands.add(args[0]); commands.add(application); commands.add(invocationUrl); commands.add("e30"); commands.add(optionalData); process = Runtime.getRuntime().exec(commands.toArray(new String[0])); stdin = new StdinJSONPipe(); stdout = new StdoutJSONPipe(); step = "I/O"; new Thread() { @Override public void run() { while (true) { try { JSONObjectReader response = post(args[1], new JSONObjectWriter().setBoolean(CONTROL_JSON, true), BACK_CHANNEL_TIMEOUT); if (response.hasProperty(NOTHING_JSON)) { logger.info("Nothing"); } else if (response.hasProperty(CLOSE_JSON)) { logger.info("Web-side close"); System.exit(3); } else { stdout.writeJSONObject(new JSONObjectWriter(response)); } } catch (Exception e) { logger.log(Level.SEVERE, "Background", e); System.exit(3); } } } }.start(); while (true) { post(args[1], new JSONObjectWriter() .setBoolean(CONTROL_JSON, false) .setObject(MESSAGE_JSON, stdin.readJSONObject()), STANDARD_TIMEOUT); } } catch (Exception e) { logger.log(Level.SEVERE, step, e); try { // Final effort telling the world that we are closing for today... post(args[1], new JSONObjectWriter(), STANDARD_TIMEOUT); } catch (IOException e1) { } System.exit(3); } } }